package cn.luyou.admin.service.impl;

import cn.luyou.admin.dto.*;
import cn.luyou.admin.entity.*;
import cn.luyou.admin.mapper.ExamRecordMapper;
import cn.luyou.admin.mapper.UserMapper;
import cn.luyou.admin.service.*;
import cn.luyou.admin.utils.BaseContext;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExamRecordServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamRecordService {

    @Autowired
    private ExamPaperService examPaperService;

    @Autowired
    private ExamPaperQuestionService examPaperQuestionService;

    @Autowired
    private ExamRecordDetailService examRecordDetailService;

    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Autowired
    private QuestionService questionService;
    @Autowired
    private UserMapper userMapper;

    @Override
    public IPage<ExamRecordDto> getRecords(Integer pageNum, Integer pageSize, Long userId, String keyword) {
        LambdaQueryWrapper<ExamRecord> wrapper = new LambdaQueryWrapper<>();
        if (userId != null) {
            wrapper.eq(ExamRecord::getUserId, userId);
        }
        if (StringUtils.hasText(keyword)) {
            wrapper.like(ExamRecord::getClassName, keyword);
        }
        wrapper.orderByDesc(ExamRecord::getCreatedTime);
        // 获取到page之后从中取出paperId，
        Page<ExamRecord> page = this.page(new Page<>(pageNum, pageSize), wrapper);
        List<ExamRecord> records = page.getRecords();
        Page<ExamRecordDto> examRecordDtoPage = new Page<>();
        List<ExamRecordDto> examRecordDtos = new ArrayList<>();
        
        for (ExamRecord record : records) {
            ExamPaper paper = examPaperService.getById(record.getPaperId());
            ExamRecordDto examRecordDto = new ExamRecordDto();
            BeanUtils.copyProperties(record, examRecordDto);
            examRecordDto.setPaperName(paper.getPaperName());
            examRecordDto.setPaperTime(paper.getDuration().toString());
            examRecordDtos.add(examRecordDto);
        }
        
        examRecordDtoPage.setRecords(examRecordDtos);
        examRecordDtoPage.setTotal(page.getTotal());
        examRecordDtoPage.setCurrent(page.getCurrent());
        examRecordDtoPage.setSize(page.getSize());
        
        return examRecordDtoPage;
    }

    @Override
    @Transactional
    public ExamRecord submitAnswers(SubmitAnswerDTO submitAnswerDTO, Long userId) {
        // 获取试卷信息
        ExamPaper paper = examPaperService.getById(submitAnswerDTO.getPaperId());
        if (paper == null) {
            throw new IllegalArgumentException("试卷不存在");
        }
        
        // 获取试卷题目
        List<ExamPaperQuestion> paperQuestions = examPaperQuestionService.getPaperQuestions(paper.getId());
        Map<Long, Integer> questionScores = paperQuestions.stream()
                .collect(Collectors.toMap(ExamPaperQuestion::getQuestionId, ExamPaperQuestion::getQuestionScore));
        System.out.println(BaseContext.getCurrentId());
        // 创建考试记录
        ExamRecord record = new ExamRecord()
                .setUserId(userId)
                .setPaperId(paper.getId())
                .setClassName(submitAnswerDTO.getClassName())
                .setDuration(submitAnswerDTO.getDuration())
                .setStatus(1);
        this.save(record);
        
        // 保存答题详情并计算总分
        examRecordDetailService.saveRecordDetails(record.getId(), submitAnswerDTO.getAnswers(), questionScores);
        List<ExamRecordDetail> details = examRecordDetailService.getRecordDetails(record.getId());
        int totalScore = details.stream().mapToInt(ExamRecordDetail::getScore).sum();
        
        // 更新总分
        record.setScore(totalScore);
        this.updateById(record);
        
        return record;
    }

    @Override
    public List<ExamRecordDetail> getRecordDetails(Long recordId) {
        return examRecordDetailService.getRecordDetails(recordId);
    }

    @Override
    public List<ExamRecordDetailDto> getWrongQuestions(Long userId) {
        List<ExamRecordDetail> wrongQuestions = examRecordDetailService.getWrongQuestions(userId);
        List<ExamRecordDetailDto> examRecordDetailDtos = new ArrayList<>();
        for (ExamRecordDetail wrongQuestion : wrongQuestions) {
            ExamRecordDetailDto examRecordDetailDto = new ExamRecordDetailDto();
            BeanUtils.copyProperties(wrongQuestion, examRecordDetailDto);
            Question byId = questionService.getById(wrongQuestion.getQuestionId());
            examRecordDetailDto.setSubject(byId.getSubject());
            examRecordDetailDto.setOptions(byId.getOptions());
            examRecordDetailDto.setDifficulty(byId.getDifficulty());
            examRecordDetailDto.setQuestionText(byId.getQuestionText());
            examRecordDetailDto.setCorrectAnswer(byId.getCorrectAnswer());
            examRecordDetailDtos.add(examRecordDetailDto);
        }
        return examRecordDetailDtos;
    }

    @Override
    public List<ExamRecord> getClassScores(String className, Long paperId) {
        return this.list(new LambdaQueryWrapper<ExamRecord>()
                .eq(ExamRecord::getClassName, className)
                .eq(paperId != null, ExamRecord::getPaperId, paperId)
                .eq(ExamRecord::getStatus, 1)
                .orderByDesc(ExamRecord::getScore));
    }

    @Override
    public List<ExamRecord> getUserScores(Long userId) {
        return this.list(new LambdaQueryWrapper<ExamRecord>()
                .eq(ExamRecord::getUserId, userId)
                .eq(ExamRecord::getStatus, 1)
                .orderByDesc(ExamRecord::getCreatedTime));
    }

    @Override
    public ScoreStatisticsDTO getClassScoreStatistics(String className, Long paperId) {
        // 获取班级所有成绩
        List<ExamRecord> records = getClassScores(className, paperId);
        
        if (records.isEmpty()) {
            return new ScoreStatisticsDTO();
        }
        
        // 计算基础统计数据
        DoubleSummaryStatistics stats = records.stream()
                .mapToDouble(ExamRecord::getScore)
                .summaryStatistics();
        
        // 计算分数段分布（0-59, 60-69, 70-79, 80-89, 90-100）
        List<Integer> scoreRanges = Arrays.asList(59, 69, 79, 89, 100);
        List<Integer> studentCounts = new ArrayList<>();
        
        for (int i = 0; i < scoreRanges.size(); i++) {
            int min = i == 0 ? 0 : scoreRanges.get(i - 1) + 1;
            int max = scoreRanges.get(i);
            
            long count = records.stream()
                    .filter(r -> r.getScore() >= min && r.getScore() <= max)
                    .count();
            studentCounts.add((int) count);
        }
        
        // 计算及格率（60分及格）
        long passCount = records.stream()
                .filter(r -> r.getScore() >= 60)
                .count();
        
        return new ScoreStatisticsDTO()
                .setScoreRanges(scoreRanges)
                .setStudentCounts(studentCounts)
                .setAverageScore(stats.getAverage())
                .setMaxScore((int) stats.getMax())
                .setMinScore((int) stats.getMin())
                .setPassCount((int) passCount)
                .setTotalCount(records.size())
                .setPassRate(passCount * 100.0 / records.size());
    }

    @Override
    public List<ExamRecord> getUserScoreTrend(Long userId, Integer limit) {
        LambdaQueryWrapper<ExamRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExamRecord::getUserId, userId)
                .eq(ExamRecord::getStatus, 1)
                .orderByDesc(ExamRecord::getCreatedTime)
                .last(limit != null, "LIMIT " + limit);
        
        return this.list(wrapper);
    }

    @Override
    public StatisticsDTO getStatistics(Long userId) {
        StatisticsDTO statistics = new StatisticsDTO();
        
        // 获取题目总数
        statistics.setQuestionCount(Math.toIntExact(questionService.count()));
        
        // 获取试卷总数
        statistics.setPaperCount(Math.toIntExact(examPaperService.count()));
        
        // 获取考试场次
        statistics.setExamCount(examRecordMapper.countByUserId(userId));
        
        // 获取平均分
        Double avgScore = examRecordMapper.getAverageScore(userId);
        statistics.setAverageScore(avgScore != null ? avgScore : 0.0);
        
        // 获取错题数量
        statistics.setWrongCount(examRecordMapper.countWrongQuestions(userId));
        
        return statistics;
    }
} 